import { ValidConfigType } from '@/api/dbms/requestvalid/types'

const validateIdent = {
  aIdentityCode_City: {
    // 城市代码列表
    11: '北京',
    12: '天津',
    13: '河北',
    14: '山西',
    15: '内蒙古',
    21: '辽宁',
    22: '吉林',
    23: '黑龙江 ',
    31: '上海',
    32: '江苏',
    33: '浙江',
    34: '安徽',
    35: '福建',
    36: '江西',
    37: '山东',
    41: '河南',
    42: '湖北 ',
    43: '湖南',
    44: '广东',
    45: '广西',
    46: '海南',
    50: '重庆',
    51: '四川',
    52: '贵州',
    53: '云南',
    54: '西藏 ',
    61: '陕西',
    62: '甘肃',
    63: '青海',
    64: '宁夏',
    65: '新疆',
    71: '台湾',
    81: '香港',
    82: '澳门',
    91: '国外 '
  },
  IdentityCode_isCardNo(card) {
    //检查号码是否符合规范，包括长度，类型
    const reg = /(^\d{15}$)|(^\d{17}(\d|X)$)/ //身份证号码为15位或者18位，15位时全为数字，18位前17位为数字，最后一位是校验位，可能为数字或字符X
    if (reg.test(card) === false) {
      return false
    }
    return true
  },
  IdentityCode_checkProvince(card) {
    //取身份证前两位，校验省份
    const province = card.substr(0, 2)
    if (validateIdent.aIdentityCode_City[province] == undefined) {
      return false
    }
    return true
  },
  IdentityCode_checkBirthday(card) {
    //检查生日是否正确，15位以'19'年份来进行补齐。
    const len = card.length
    //身份证15位时，次序为省（3位）市（3位）年（2位）月（2位）日（2位）校验位（3位），皆为数字
    if (len == '15') {
      const re_fifteen = /^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/
      const arr_data = card.match(re_fifteen) // 正则取号码内所含出年月日数据
      const year = arr_data[2]
      const month = arr_data[3]
      const day = arr_data[4]
      const birthday = new Date('19' + year + '/' + month + '/' + day)
      return validateIdent.IdentityCode_verifyBirthday('19' + year, month, day, birthday)
    }
    //身份证18位时，次序为省（3位）市（3位）年（4位）月（2位）日（2位）校验位（4位），校验位末尾可能为X
    if (len == '18') {
      const re_eighteen = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/
      const arr_data = card.match(re_eighteen) // 正则取号码内所含出年月日数据
      const year = arr_data[2]
      const month = arr_data[3]
      const day = arr_data[4]
      const birthday = new Date(year + '/' + month + '/' + day)
      return validateIdent.IdentityCode_verifyBirthday(year, month, day, birthday)
    }
    return false
  },
  IdentityCode_verifyBirthday(year, month, day, birthday) {
    //校验日期 ，15位以'19'年份来进行补齐。
    const now = new Date()
    const now_year = now.getFullYear()
    //年月日是否合理
    if (
      birthday.getFullYear() == year &&
      birthday.getMonth() + 1 == month &&
      birthday.getDate() == day
    ) {
      //判断年份的范围（3岁到150岁之间)
      const time = now_year - year
      if (time >= 3 && time <= 150) {
        return true
      }
      return false
    }
    return false
  },
  IdentityCode_checkParity(card) {
    //校验位的检测
    card = validateIdent.IdentityCode_changeFivteenToEighteen(card) // 15位转18位
    const len = card.length
    if (len == '18') {
      const arrInt = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
      const arrCh = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
      let cardTemp = 0
      let i
      for (i = 0; i < 17; i++) {
        cardTemp += card.substr(i, 1) * arrInt[i]
      }
      const valnum = arrCh[cardTemp % 11]
      if (valnum == card.substr(17, 1)) {
        return true
      }
      return false
    }
    return false
  },
  IdentityCode_changeFivteenToEighteen(card) {
    //15位转18位身份证号
    if (card.length == '15') {
      const arrInt = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
      const arrCh = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
      let cardTemp = 0,
        i
      card = card.substr(0, 6) + '19' + card.substr(6, card.length - 6)
      for (i = 0; i < 17; i++) {
        cardTemp += card.substr(i, 1) * arrInt[i]
      }
      card += arrCh[cardTemp % 11]
      return card
    }
    return card
  },
  IdentityCodeValid(card) {
    //   身份证号码检验主入口
    let pass = true
    //是否为空
    if (pass && card === '') pass = false
    //校验长度，类型
    if (pass && validateIdent.IdentityCode_isCardNo(card) === false) pass = false
    //检查省份
    if (pass && validateIdent.IdentityCode_checkProvince(card) === false) pass = false
    //校验生日
    if (pass && validateIdent.IdentityCode_checkBirthday(card) === false) pass = false
    //检验位的检测
    if (pass && validateIdent.IdentityCode_checkParity(card) === false) pass = false
    if (pass) {
      return true
    } else {
      return false
    }
  }
}

//Luhm校验（新）
const luhnCheck = (bankCard) => {
  //取出最后一位（与luhn进行比较）
  const lastNum = bankCard.substr(bankCard.length - 1, 1)

  //前15或18位
  const first15Num = bankCard.substr(0, bankCard.length - 1)
  const newArr: string[] = []
  for (let i = first15Num.length - 1; i > -1; i--) {
    //前15或18位倒序存进数组
    newArr.push(first15Num.substr(i, 1))
  }
  const arrJiShu: number[] = [] //奇数位*2的积 <9
  const arrJiShu2: number[] = [] //奇数位*2的积 >9

  const arrOuShu: number[] = [] //偶数位数组
  for (let j = 0; j < newArr.length; j++) {
    if ((j + 1) % 2 == 1) {
      //奇数位
      if (parseInt(newArr[j]) * 2 < 9) arrJiShu.push(parseInt(newArr[j]) * 2)
      else arrJiShu2.push(parseInt(newArr[j]) * 2)
    } //偶数位
    else {
      arrOuShu.push(Number(newArr[j]))
    }
  }

  const jishu_child1: number[] = [] //奇数位*2 >9 的分割之后的数组个位数
  const jishu_child2: number[] = [] //奇数位*2 >9 的分割之后的数组十位数
  for (let h = 0; h < arrJiShu2.length; h++) {
    jishu_child1.push(arrJiShu2[h] % 10)
    jishu_child2.push(arrJiShu2[h] / 10)
  }

  let sumJiShu = 0 //奇数位*2 < 9 的数组之和
  let sumOuShu = 0 //偶数位数组之和
  let sumJiShuChild1 = 0 //奇数位*2 >9 的分割之后的数组个位数之和
  let sumJiShuChild2 = 0 //奇数位*2 >9 的分割之后的数组十位数之和
  let sumTotal = 0
  for (let m = 0; m < arrJiShu.length; m++) {
    sumJiShu = sumJiShu + arrJiShu[m]
  }

  for (let n = 0; n < arrOuShu.length; n++) {
    sumOuShu = sumOuShu + arrOuShu[n]
  }

  for (let p = 0; p < jishu_child1.length; p++) {
    sumJiShuChild1 = sumJiShuChild1 + jishu_child1[p]
    sumJiShuChild2 = sumJiShuChild2 + jishu_child2[p]
  }
  //计算总和
  sumTotal = sumJiShu + sumOuShu + sumJiShuChild1 + sumJiShuChild2

  //计算luhn值
  const k = sumTotal % 10 == 0 ? 10 : sumTotal % 10
  const luhn = 10 - k

  if (lastNum == luhn) {
    return true
  } else {
    return false
  }
}

export const ruleConfig = {
  //长度校验
  'org.scboy.dbms.valid.common.LengValid': (config: ValidConfigType, value: any) => {
    let max: number = 0
    let min: number = 0

    //判断是否在长度范围
    if (config.expression.indexOf('-') > -1) {
      const exp: string[] = config.expression.split('-')
      if (exp[0]) {
        min = Number(exp[0])
      }
      if (exp[1]) {
        max = Number(exp[1])
      }
      const length = String(value).length
      if (length < min || length > max) {
        return {
          check: false,
          msg: 'validate.length',
          params: { start: min, end: max }
        }
      } else {
        return { check: true }
      }
    } else {
      //固定长度
      const length = Number(config.expression)
      if (String(value).length == length) {
        return { check: true }
      } else {
        return {
          check: false,
          msg: 'validate.lengthEq',
          params: { start: length }
        }
      }
    }
  },
  //长度校验
  'org.scboy.dbms.valid.common.ArrayLengValid': (config: ValidConfigType, value: any) => {
    let max: number = 0
    let min: number = 0

    if (!(value instanceof Array)) {
      return {
        check: false,
        msg: 'validate.noArray',
        params: { start: 0, end: 0 }
      }
    }
    //判断是否在长度范围
    if (config.expression.indexOf('-') > -1) {
      const exp: string[] = config.expression.split('-')
      if (exp[0]) {
        min = Number(exp[0])
      }
      if (exp[1]) {
        max = Number(exp[1])
      }
      const length = value.length
      if (length < min || length > max) {
        return {
          check: false,
          msg: 'validate.arrayLength',
          params: { start: min, end: max }
        }
      } else {
        return { check: true }
      }
    } else {
      //固定长度
      const length = Number(config.expression)
      if (value.length == length) {
        return { check: true }
      } else {
        return {
          check: false,
          msg: 'validate.arrayLengthEq',
          params: { start: length }
        }
      }
    }
  },
  //正则校验
  'org.scboy.dbms.valid.common.RegxValid': (config: ValidConfigType, value: any) => {
    const val = String(value)
    const re = new RegExp(config.expression)
    return { check: re.test(val), msg: config.msg }
  },
  //数值校验
  'org.scboy.dbms.valid.common.ValueValid': (config: ValidConfigType, value: any) => {
    let max: number = 0
    let min: number = 0

    //判断是否在长度范围
    if (config.expression.indexOf('-') > -1) {
      const exp: string[] = config.expression.split('-')
      if (exp[0]) {
        min = Number(exp[0])
      }
      if (exp[1]) {
        max = Number(exp[1])
      }
      const val = Number(value)
      if (val < min || val > max) {
        return {
          check: false,
          msg: 'validate.value',
          params: { start: min, end: max }
        }
      } else {
        return { check: true }
      }
    } else {
      //固定长度
      const val = Number(config.expression)
      if (Number(value) == val) {
        return { check: true }
      } else {
        return { check: false, msg: 'validate.valueEq', params: { start: val } }
      }
    }
  },
  //银行卡
  'org.scboy.dbms.valid.datatype.BankCardValid': (_config: ValidConfigType, value: any) => {
    const backCard = String(value)

    //判断是否为全部是数值
    const numRegex = /^\d*$/
    if (numRegex.test(backCard)) {
      return { check: false, msg: 'validate.bankCard' }
    }

    //长度判断
    if (backCard.length < 15 || backCard.length > 19) {
      return { check: false, msg: 'validate.bankCardLength' }
    }
    if (!luhnCheck(backCard)) {
      return { check: false, msg: 'validate.bankCardError' }
    } else {
      return { check: true }
    }
  },
  //汉字
  'org.scboy.dbms.valid.datatype.ChineseValid': (_config: ValidConfigType, value: any) => {
    const reg = /^[\u4e00-\u9fa5]+$/
    const cValue = String(value)
    return { check: reg.test(cValue), msg: 'validate.chinese' }
  },
  //浮点数
  'org.scboy.dbms.valid.datatype.DoubleValid': (config: ValidConfigType, value: any) => {
    const val = String(value)
    if (val.indexOf('.') == 0) {
      return { check: false, msg: 'validate.double' }
    }
    if (val.indexOf('.') > -1) {
      if (val.split('.')[1].length > Number(config.size)) {
        return {
          check: false,
          msg: 'validate.doubleLength',
          params: { start: Number(config.size) }
        }
      } else {
        return { check: true }
      }
    } else {
      return { check: true }
    }
  },
  //邮箱
  'org.scboy.dbms.valid.datatype.EmailValid': (_config: ValidConfigType, value: any) => {
    const reg = /^([0-9a-zA-Z_\.\-\u4e00-\u9fa5])+\@([0-9a-zA-Z_\.\-\])+\.([a-zA-Z]{2,8})$/
    const cValue = String(value)
    return { check: reg.test(cValue), msg: 'validate.email' }
  },
  //身份证
  'org.scboy.dbms.valid.datatype.IDCartValid': (_config: ValidConfigType, value: any) => {
    return { check: validateIdent.IdentityCodeValid(value), msg: 'validate.idCard' }
  },
  //整数
  'org.scboy.dbms.valid.datatype.IntValid': (_config: ValidConfigType, value: any) => {
    const str = String(value)
    if (str.indexOf('.') > -1) {
      return { check: false, msg: 'validate.int' }
    }
    if (Number(value)) {
      return { check: true }
    } else {
      return { check: false, msg: 'validate.int' }
    }
  },
  //IP地址
  'org.scboy.dbms.valid.datatype.IPValid': (_config: ValidConfigType, value: any) => {
    const regexIP =
      /^((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))$/

    return { check: regexIP.test(value), msg: 'validate.ip' }
  },
  //JS规则验证
  'org.scboy.dbms.valid.datatype.JSValid': (config: ValidConfigType, value: any, params) => {
    const check = eval(
      '(()=>{ var value="' +
        value +
        '";var params=' +
        JSON.stringify(params) +
        ';' +
        config.js +
        '})()'
    )
    return { check: check, msg: config.msg }
  },
  //座机
  'org.scboy.dbms.valid.datatype.MobileValid': (_config: ValidConfigType, value: any) => {
    const regex =
      /^((0\d{2,3}(-)?\d{7,8})|(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8})$/

    return { check: regex.test(value), msg: 'validate.mobile' }
  },
  //数值
  'org.scboy.dbms.valid.datatype.NumberValid': (_config: ValidConfigType, value: any) => {
    if (Number(value)) {
      return { check: true }
    } else {
      return { check: false, msg: 'validate.number' }
    }
  },
  //手机号码
  'org.scboy.dbms.valid.datatype.TelephoneValid': (_config: ValidConfigType, value: any) => {
    const regex = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
    return { check: regex.test(value), msg: 'validate.telephone' }
  },
  //网址
  'org.scboy.dbms.valid.datatype.UrlValid': (_config: ValidConfigType, value: any) => {
    const regex = /^(https|http|ftp)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}(:[0-9]{1,5})?(\/[\S]*)?$/
    return { check: regex.test(value), msg: 'validate.url' }
  }
}
